package com.hcc.flow.server.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.filter.OncePerRequestFilter;

import com.hcc.flow.server.common.utils.CommUtil;
import com.hcc.flow.server.common.utils.StringUtilsV2;
import com.hcc.flow.server.model.common.LoginUser;
import com.hcc.flow.server.service.sys.TokenService;

/**
 * Token过滤器
 * 
 * @author 韩长长 
 *
 *         2020年6月14日
 */
@Component
public class TokenFilter extends OncePerRequestFilter {

	private static final String TOKEN_KEY = "token";

	@Autowired
	private TokenService tokenService;
	@Autowired
	private UserDetailsService userDetailsService;
	
	private static final Long MINUTES_10 = 10 * 60 * 1000L;

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		String token = getToken(request);
		if (StringUtilsV2.isNotBlank(token) && !"undefined".equals(token)) {
			LoginUser loginUser = tokenService.getLoginUser(token);
			if (loginUser != null) {
				loginUser = checkLoginTime(loginUser);
				UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(loginUser,
						null, loginUser.getAuthorities());
				// 用于记录当前用户
				SecurityContextHolder.getContext().setAuthentication(authentication);
			}
		}
		filterChain.doFilter(request, response);
	}

	/**
	 * 校验时间<br>
	 * 过期时间与当前时间对比，临近过期10分钟内的话，自动刷新缓存
	 * 
	 * @param loginUser
	 * @return
	 */
	private LoginUser checkLoginTime(LoginUser loginUser) {
		long expireTime = loginUser.getExpireTime();
		long currentTime = System.currentTimeMillis();
		if (expireTime - currentTime <= MINUTES_10) {
			String token = loginUser.getToken();
			loginUser = (LoginUser) userDetailsService.loadUserByUsername(loginUser.getUsername());
			loginUser.setToken(token);
			tokenService.refresh(loginUser,false,null);
		}
		return loginUser;
	}

	/**
	 * 根据参数或者header获取token
	 * 
	 * @param request
	 * @return
	 */
	public static String getToken(HttpServletRequest request) {
		if(request == null) {
    		request = getHttpServletRequest();
    	}
		String token = request.getParameter(TOKEN_KEY);
		if (StringUtilsV2.isBlank(token)) {
			token = request.getHeader(TOKEN_KEY);
		}
		return token;
	}
	/**
	 * 根据参数或者header获取token
	 * 
	 * @param request
	 * @return
	 */
	public static Integer getSysId(HttpServletRequest request) {
		if(request == null) {
    		request = getHttpServletRequest();
    	}
		String sysid = request.getHeader("sysid");
		if (StringUtilsV2.isBlank(sysid)) {
			sysid = request.getParameter("sysid");
		}
		if (StringUtilsV2.isBlank(sysid)) {
			return 1;
		}
		return CommUtil.null2Int(sysid);
	}

	/** 
     * 获取当前请求session 
     * @return 
     */  
    public static HttpServletRequest getHttpServletRequest(){  
    	return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); 
    }    
	
}
